import { Component, Vue } from 'vue-property-decorator'

@Component
export default class Emitter extends Vue {
    dispatch(componentName: string, eventName: string, params?: any) {
        let parent = this.$parent || this.$root
        let name = parent.$options.name

        while (parent && (!name || name !== componentName)) {
            parent = parent.$parent

            if (parent) {
                name = parent.$options.name
            }
        }
        if (parent) {
            // @ts-ignore
            // eslint-disable-next-line prefer-spread
            parent.$emit.apply(parent, [eventName].concat(params))
        }
    }

    broadcast(componentName: string, eventName: string, params?: any) {
        broadcast.call(this, componentName, eventName, params)
    }
}

function broadcast(
    this: Vue,
    componentName: string,
    eventName: string,
    params?: any
) {
    this.$children.forEach(child => {
        const name = child.$options.name

        if (name === componentName) {
            // @ts-ignore
            // eslint-disable-next-line prefer-spread
            child.$emit.apply(child, [eventName].concat(params))
        } else {
            // @ts-ignore
            // 如果 params 是空数组，接收到的会是 undefined
            broadcast.apply(child, [componentName, eventName].concat([params]))
        }
    })
}
